﻿/* 数字转汉字大写
 */

namespace LSLib.StringEx
{
    using System;

    public static class NumberInWords
    {
        /// <summary>常量：目前支持的最大长度
        /// </summary>
        private const int MAXLENGHT = 16;

        /// <summary>有效性检查
        /// </summary>
        /// <param name="inputNum"></param>
        private static bool ValidityChecked(string inputNum)
        {
            if (string.IsNullOrEmpty(inputNum)) throw new ArgumentNullException("inputNum");
            if (inputNum.Length > MAXLENGHT) throw new ArgumentOutOfRangeException("inputNum", inputNum, string.Format("数字过大，暂时不提供超过{0}位的数字转换！", MAXLENGHT));

            //验证是否为整数，暂时不支持小数
            foreach (char item in inputNum)
            {
                if (char.IsNumber(item) == false)
                    throw new ArgumentException(string.Format("inputNum不是整数！inputNum={0}", inputNum), "inputNum");
            }
            return true;
        }

        /// <summary>数字转换为汉字显示
        /// </summary>
        /// <param name="inputNum">输入的整数型数字</param>
        public static string ConvertNumberInWords(int inputNum)
        {
            return ConvertNumberInWords(inputNum.ToString());
        }
        /// <summary>数字转换为汉字显示
        /// </summary>
        /// <param name="inputNum">输入的长整数型数字</param>
        public static string ConvertNumberInWords(long inputNum)
        {
            return ConvertNumberInWords(inputNum.ToString());
        }
        /// <summary>数字转换为汉字显示
        /// </summary>
        /// <param name="inputNum">输入的数字字符串</param>
        /// <returns></returns>
        public static string ConvertNumberInWords(string inputNum)
        {
            if (ValidityChecked(inputNum) == false) return string.Empty;

            //数字转换为中文后的数组 
            string[] num = new string[] { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
            //为数字位数建立一个位数组 
            string[] digit = new string[] { "", "拾", "佰", "仟" };
            //为数字单位建立一个单位数组 
            string[] units = new string[] { "", "万", "亿", "万亿" };

            //返回值
            string result = string.Empty;
            //字符位置指针 
            int finger = 0;

            //取模
            int m = inputNum.Length % 4;
            int k = 0;
            if (m > 0)
                k = inputNum.Length / 4 + 1;
            else
                k = inputNum.Length / 4;

            //外层循环,四位一组,每组最后加上单位：units中的值
            for (int i = k; i > 0; i--)
            {
                int L = 4;
                if (i == k && m != 0) L = m;

                //得到一组四位数 
                string four = inputNum.Substring(finger, L);
                int l = four.Length;
                //内层循环在该组中的每一位数上循环  
                for (int j = 0; j < l; j++)
                {
                    //处理组中的每一位数加上所在的位 
                    int n = System.Convert.ToInt32(four.Substring(j, 1));
                    if (n == 0)
                    {
                        if (j < l - 1 && System.Convert.ToInt32(four.Substring(j + 1, 1)) > 0 && !result.EndsWith(num[n]))
                            result += num[n];
                    }
                    else
                    {
                        if (!(n == 1 && (result.EndsWith(num[0]) | result.Length == 0) && j == l - 2))
                            result += num[n];
                        result += digit[l - j - 1];
                    }
                }
                finger += L;

                //每组最后加上一个单位:",万,",",亿," 等 
                if (i < k) //如果不是最高位的一组 
                {
                    if (System.Convert.ToInt32(four) != 0)
                        //如果所有4位不全是0则加上单位",万,",",亿,"等 
                        result += units[i - 1];
                }
                else
                {
                    //处理最高位的一组,最后必须加上单位 
                    result += units[i - 1];
                }
            }
            return result;
        }
    }
}
